rmb();
shadow_tv.tv_sec = HYPERVISOR_shared_info->wc_sec;
shadow_tv.tv_usec = HYPERVISOR_shared_info->wc_usec;
- shadow_tsc_stamp = HYPERVISOR_shared_info->tsc_timestamp.tsc_bits;
+ shadow_tsc_stamp =
+ (u32)(HYPERVISOR_shared_info->tsc_timestamp >> rdtsc_bitshift);
shadow_system_time = HYPERVISOR_shared_info->system_time;
rmb();
}
{
unsigned long long alarm;
u64 __cpu_khz, cpu_freq, scale, scale2;
+ unsigned int cpu_ghz;
__cpu_khz = HYPERVISOR_shared_info->cpu_freq;
do_div(__cpu_khz, 1000);
xtime.tv_usec = HYPERVISOR_shared_info->wc_usec;
processed_system_time = shadow_system_time;
- rdtsc_bitshift = HYPERVISOR_shared_info->tsc_timestamp.tsc_bitshift;
- cpu_freq = HYPERVISOR_shared_info->cpu_freq;
+ cpu_freq = HYPERVISOR_shared_info->cpu_freq;
+
+ cpu_ghz = do_div(cpu_freq, 1000000000UL);
+ for ( rdtsc_bitshift = 0; cpu_ghz != 0; rdtsc_bitshift++, cpu_ghz >>= 1 )
+ continue;
scale = 1000000LL << (32 + rdtsc_bitshift);
do_div(scale, (u32)cpu_freq);
rmb();
shadow_tv.tv_sec = s->wc_sec;
shadow_tv.tv_usec = s->wc_usec;
- shadow_tsc_stamp = s->tsc_timestamp.tsc_bits;
+ shadow_tsc_stamp = (u32)s->tsc_timestamp;
shadow_system_time = s->system_time;
rmb();
}
*/
static unsigned long fast_gettimeoffset_quotient;
-unsigned int rdtsc_bitshift;
extern u32 shadow_tsc_stamp;
extern u64 shadow_system_time;
rdtsc(eax,edx);
/* .. relative to previous jiffy (32 bits is enough) */
- eax -= (shadow_tsc_stamp << rdtsc_bitshift) & 0xffffffff;
+ eax -= shadow_tsc_stamp;
/*
* Time offset = (tsc_low delta) * fast_gettimeoffset_quotient
/* atomically read monotonic base & last_offset */
do {
seq = read_seqbegin(&monotonic_lock);
- last_offset = monotonic_offset << rdtsc_bitshift;
+ last_offset = monotonic_offset;
base = monotonic_base;
} while (read_seqretry(&monotonic_lock, seq));
"0" (eax), "1" (edx));
}
- rdtsc_bitshift = HYPERVISOR_shared_info->tsc_timestamp.tsc_bitshift;
-
set_cyc2ns_scale(cpu_khz/1000);
rdtscll(alarm);
static u64 cpu_freq; /* CPU frequency (Hz) */
static u32 st_scale_f; /* Cycles -> ns, fractional part */
static u32 st_scale_i; /* Cycles -> ns, integer part */
-static u32 tsc_irq; /* CPU0's TSC at last 'time update' */
+static u32 shifted_tsc_irq; /* CPU0's TSC at last 'time update' */
+static u64 full_tsc_irq; /* ...ditto, but all 64 bits */
static s_time_t stime_irq; /* System time at last 'time update' */
static unsigned long wc_sec, wc_usec; /* UTC time at last 'time update'. */
static rwlock_t time_lock = RW_LOCK_UNLOCKED;
static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- u64 full_tsc;
-
write_lock_irq(&time_lock);
#ifdef CONFIG_X86_IO_APIC
* Updates TSC timestamp (used to interpolate passage of time between
* interrupts).
*/
- rdtscll(full_tsc);
- tsc_irq = (u32)(full_tsc >> rdtsc_bitshift);
+ rdtscll(full_tsc_irq);
+ shifted_tsc_irq = (u32)(full_tsc_irq >> rdtsc_bitshift);
/* Update jiffies counter. */
(*(unsigned long *)&jiffies)++;
rdtscll(tsc);
low = (u32)(tsc >> rdtsc_bitshift);
- delta_tsc = (s32)(low - tsc_irq);
+ delta_tsc = (s32)(low - shifted_tsc_irq);
if ( unlikely(delta_tsc < 0) ) delta_tsc = 0;
delta = ((u64)delta_tsc * st_scale_f);
delta >>= 32;
wmb();
si->cpu_freq = cpu_freq;
- si->tsc_timestamp.tsc_bitshift = rdtsc_bitshift;
- si->tsc_timestamp.tsc_bits = tsc_irq;
+ si->tsc_timestamp = full_tsc_irq;
si->system_time = stime_irq;
si->wc_sec = wc_sec;
si->wc_usec = wc_usec;
int __init init_xen_time()
{
u64 scale;
- u64 full_tsc;
unsigned int cpu_ghz;
cpu_ghz = (unsigned int)(cpu_freq / 1000000000ULL);
st_scale_i = scale >> 32;
/* System time ticks from zero. */
- rdtscll(full_tsc);
+ rdtscll(full_tsc_irq);
stime_irq = (s_time_t)0;
- tsc_irq = (u32)(full_tsc >> rdtsc_bitshift);
+ shifted_tsc_irq = (u32)(full_tsc_irq >> rdtsc_bitshift);
/* Wallclock time starts as the initial RTC time. */
wc_sec = get_cmos_time();
unsigned long ss;
} PACKED execution_context_t;
-typedef struct {
- u32 tsc_bits; /* 0: 32 bits read from the CPU's TSC. */
- u32 tsc_bitshift; /* 4: 'tsc_bits' uses N:N+31 of TSC. */
-} PACKED tsc_timestamp_t; /* 8 bytes */
+typedef u64 tsc_timestamp_t; /* RDTSC timestamp */
/*
* The following is all CPU context. Note that the i387_ctxt block is filled
unsigned long ss;
} PACKED execution_context_t;
-/*
- * NB. This may become a 64-bit count with no shift. If this happens then the
- * structure size will still be 8 bytes, so no other alignments will change.
- */
-typedef struct {
- u32 tsc_bits; /* 0: 32 bits read from the CPU's TSC. */
- u32 tsc_bitshift; /* 4: 'tsc_bits' uses N:N+31 of TSC. */
-} PACKED tsc_timestamp_t; /* 8 bytes */
+typedef u64 tsc_timestamp_t; /* RDTSC timestamp */
/*
* The following is all CPU context. Note that the i387_ctxt block is filled